Skip to content

Retry a fetch race as git 2.52 words it, and lead a git failure's cause with git's error line - #310

Merged
JacobStephens2 merged 2 commits into
mainfrom
issue-309
Oct 2, 2026
Merged

JacobStephens2 merged 2 commits into
mainfrom
issue-309

Conversation

@JacobStephens2

Copy link
Copy Markdown
Owner

Summary

Two fixes in Git::run, both in src/git.rs.

A git command that loses a ref-update race is run again, in git 2.52's wording as well as the older one:

 held_lock(stderr)
   ".lock': File exists"
   "could not lock config file"
   "cannot lock ref" and "but expected"
+  "incorrect old value provided"

A failed git command's message leads with git's own error line, so the first line of a child Run's cause, which is all a Ticket's line shows, says what went wrong:

-git fetch origin issue-1346 failed: From https://github.com/<owner>/<repo>
-* branch                issue-1346 -> FETCH_HEAD
-93d814703..8cf48f061  issue-1346 -> origin/issue-1346
-error: fetching ref refs/remotes/origin/issue-1346 failed: incorrect old value provided
+git fetch origin issue-1346 failed: error: fetching ref refs/remotes/origin/issue-1346 failed: incorrect old value provided
+From https://github.com/<owner>/<repo>
+* branch                issue-1346 -> FETCH_HEAD
+93d814703..8cf48f061  issue-1346 -> origin/issue-1346
on(git exits non-zero, once the retries are over)
  stderr lines = the first line starting "error:" or "fatal:", if any,
                 then the last of the others, 10 lines in all
  message      = "git <args> failed: " + stderr lines + last 10 stdout lines

With no error: or fatal: line the message reads as before.

Seams tested: Git::run; the reading back of a child Run's ending (run_ending); a Ticket's line in a Spec run's summary (summarize in spec_run).

Evidence

  • Before: a_ref_another_git_moved_meanwhile_is_tried_again, given the 2.52 wording, failed: git … race failed: error: fetching ref refs/remotes/origin/main failed: incorrect old value provided. a_failure_starts_with_gits_own_error_line failed: the first line ended fetch-main failed: From https://github.com/acme/widgets.
    After: both pass, with gits_own_error_line_is_kept_however_many_lines_follow_it and a_failed_tickets_line_says_its_cause (#23 failed: git fetch origin issue-21 failed: error: …). cargo test: every suite passes, 140 unit tests among them. cargo clippy --all-targets: clean.
  • The last two tests named, and the reworded a_cause_of_several_lines_reads_back_as_its_first_line, passed as soon as they were written: they pin behaviour run_ending and spec_run already had.
  • Not reproduced against a real git 2.52: this machine has git 2.43.0, so the race is a git alias that writes the 2.52 error on its first attempt.

Merge Danger

Door: two-way

A revert restores the old message order and retry condition; nothing is stored.

Blast Radius: messages

Every failed git command's cause now starts with its error: or fatal: line wherever it shows: the end of a Run, a Ticket's line, the Tickets checklist, the Run notification. A stderr whose first such line comes before its last 10 lines now reports that line plus the last 9 others, where it reported the last 10. Any git command whose stderr contains incorrect old value provided is retried for up to 10 seconds before failing.

Unaddressed findings

Standards

  • held_lock no longer names only held locks (possible Mysterious Name): kept, since the Agent Brief names held_lock as the interface that recognises the new wording. Its doc comment, Git::run's and LOCK_WAIT's now all name the ref race.
  • Test-only edits in run_ending.rs and spec_run.rs for a change made in git.rs (possible Shotgun Surgery, and the fetch cause repeated across test modules): partly addressed. The added run_ending test is gone, with the existing several-lines test reworded to a git failure's shape instead. The summarize test stays because the acceptance criteria ask for a Ticket's line, and each module's test fixtures are private to it.

Spec

  • No single test chains Git::run's real message through the read-back to a Ticket's line: the three steps live in three modules with private test helpers; each is tested at its own seam, and an end-to-end test would need a real fetch race.
  • The loop over both wordings does not say which one failed: the panic message carries the git command, which contains the wording.
  • incorrect old value provided is matched anywhere in stderr, not anchored on fetching ref: this is what the brief asks for, and it also covers the same race reported by a command other than fetch.
  • A hook's own error: line on stderr, written before git's, leads the message: consistent with "the first such line"; telling a hook's line from git's is not possible from stderr alone.

Closes #309

🤖 Generated with Claude Code

JacobStephens2 and others added 2 commits October 2, 2026 13:42
…git's error line

A git command that fails with 'incorrect old value provided' is run again
like the other cases of a ref another git moved meanwhile. A failed git
command's message now has git's first 'error:' or 'fatal:' line right after
'git <args> failed: ', so the first line of a child Run's cause, which is
all a Ticket's line shows, says what went wrong instead of a banner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…elper named for what it does, a cause of several lines tested with a git failure's own shape

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JacobStephens2
JacobStephens2 merged commit 7c71459 into main Oct 2, 2026
13 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-309 branch October 2, 2026 17:58
@JacobStephens2 JacobStephens2 mentioned this pull request Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A Ticket's Run fails on a fetch race newer git words differently, and its cause shows only git's banner line

1 participant